using System;

using System.Collections;
using System.Configuration;


namespace blackhouse.Web.ViewState {
	public class ViewStateServiceManager {
		// This uses an array and mod to cycle repeatedly through an array (so limited size)

		//WARNING:  When the user uses the "back" button on the browser, IE will not rerequest the page, so 
		// if the user posts again they need the viewstate to still be present on the server.  Need to set the VIEW_STATE_NUM_PAGES
		// to a tradeoff of number of back pages allowed and 
		// the amount of memory consumed by the viewstate kept per page.  
		private const short VIEW_STATE_NUM_PAGES = 1;		//Number of pages to keep viewstate for

		//Name of storage location for viewstate information
		//	private const string SESSION_VIEW_STATE_MGR = "VIEW_STATE_MGR1";
		private static string SESSION_VIEW_STATE_MGR = System.Web.HttpContext.Current.Session.SessionID.ToString();
		private long pageCount = 0;	//Number of pages seen by this customer 
		private string[] ViewStates = new string[VIEW_STATE_NUM_PAGES];	//Store for viewstates

		
		public static string ViewStateStore {
			get {
				string viewStateStore = Convert.ToString(ConfigurationManager.AppSettings["ViewStateStore"]);
				if (string.IsNullOrEmpty(viewStateStore)) viewStateStore = "cache";
				return viewStateStore;
			}

		}

		public ViewStateServiceManager() { }

		public long SaveViewState(string szViewState) {
			//Increment the total page seen counter
			pageCount++;

			//Now use the modulas operator (%) to find remainder of that and size of viewstate storage, this creates a
			// circular array where it continually cycles through the array index range (effectively keeps
			// the last requests to match size of storage)
			short siIndex = (short)(pageCount % VIEW_STATE_NUM_PAGES);

			//Now save the viewstate for this page to the current position.  
			ViewStates[siIndex] = szViewState;

			return pageCount;
		}


		public string GetViewState(long lRequestNumber) {
			//Could cycle though the array and make sure that the given request number is actually
			// present (in case the array is not big enough).  Much faster to just take the
			// given request number and recalculate where it should be stored
			short siIndex = (short)(lRequestNumber % VIEW_STATE_NUM_PAGES);

			return ViewStates[siIndex];
		}


		public static ViewStateServiceManager GetViewStateServiceManager() {
			ViewStateServiceManager oViewStateMgr = null;

			// SESSION
			if (ViewStateServiceManager.ViewStateStore == "session") {
				if (null == System.Web.HttpContext.Current.Session[SESSION_VIEW_STATE_MGR]) {
					oViewStateMgr = new ViewStateServiceManager();
					System.Web.HttpContext.Current.Session[SESSION_VIEW_STATE_MGR] = oViewStateMgr;
				}
				else {
					oViewStateMgr = (ViewStateServiceManager)System.Web.HttpContext.Current.Session[SESSION_VIEW_STATE_MGR];
				}
			}

			// APPLICATION
			if (ViewStateServiceManager.ViewStateStore == "application") {

				if (null == System.Web.HttpContext.Current.Application[SESSION_VIEW_STATE_MGR]) {
					oViewStateMgr = new ViewStateServiceManager();
					System.Web.HttpContext.Current.Application[SESSION_VIEW_STATE_MGR] = oViewStateMgr;
				}
				else {
					oViewStateMgr = (ViewStateServiceManager)System.Web.HttpContext.Current.Application[SESSION_VIEW_STATE_MGR];
				}
			}

			//CACHE

			if (ViewStateServiceManager.ViewStateStore == "cache") {

				if (null == System.Web.HttpContext.Current.Cache[SESSION_VIEW_STATE_MGR]) {
					oViewStateMgr = new ViewStateServiceManager();
					System.Web.HttpContext.Current.Cache[SESSION_VIEW_STATE_MGR] = oViewStateMgr;
				}
				else {
					oViewStateMgr = (ViewStateServiceManager)System.Web.HttpContext.Current.Cache[SESSION_VIEW_STATE_MGR];
				}
			}

			return oViewStateMgr;
		}
	}
}
